home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / parse1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  36.4 KB  |  1,193 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains the Harvest C parser.  The parser is hand written,
  35.  * recursive descent.
  36.  * 
  37.  * 
  38.  */
  39.  
  40.  
  41. #include "conditcomp.h"
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include "structs.h"
  45.  
  46. #include "CHarvestDoc.h"
  47. #include "CHarvestOptions.h"
  48.  
  49. extern CHarvestDoc *gProject;
  50.  
  51. #pragma segment Parse1
  52.  
  53. /* THEPARSER */
  54.  
  55. /*
  56.  * Parsing:  We conceptually separate parsing into 2 stages : syntactic
  57.  * parsing and semantic parsing.  During syntactic parsing, we wish to
  58.  * identify all problems occuring in syntax only - such as unmatched parens.
  59.  * During semantic parsing, we wish to identify all other problems which will
  60.  * prohibit us from producing assembler output.  These problems include : use
  61.  * of an undefined identifier, type mismatches, etc...
  62.  */
  63. /*
  64.  * This compiler does not implement volatile.
  65.  */
  66.  
  67. /*
  68.  * Every routine which returns an expression, must set the type of that
  69.  * expression and whether or not it is an lvalue.  In fact, any such routine
  70.  * should have the following four items, for every call to BuildTree*().  1.
  71.  * The BuildTree*() call itself, 2.  Explicit setting of the type, 3.
  72.  * Explicit setting of the LValue status, and 4.  a TYPERULE comment,
  73.  * explaining what the rules behind that set were.  TYPERULE comments may
  74.  * also explain limitations on operands and the like.
  75.  */
  76.  
  77. FloatLitVia_t
  78. RawFloatLit(void)
  79. {
  80.     register FloatLitVia_t          raw;
  81.     raw = (FloatLitVia_t) Ealloc(sizeof(FloatLit_t));
  82.     Via(raw)->next = NULL;
  83.     Via(raw)->FloatFlags = 0;
  84.     Via(raw)->Loc = BuildARegLabelDisplace(5, MakeFloatLitLabel(NextFloatLitLabel++));
  85.     SetLocSZ(Via(raw)->Loc, M68_TypeSize(BuildTypeRecord(0, TRC_longdouble, SGN_unknown)));
  86.     SetLocIsFloat(Via(raw)->Loc, 1);
  87.     Via(raw)->val.num = 0;
  88.     return raw;
  89. }
  90.  
  91. FloatLitVia_t
  92. AddFloatLit(long double x)
  93. {
  94.     FloatLitVia_t                   temp;
  95.     temp = RawFloatLit();
  96.     Via(temp)->next = FloatList;
  97.     Via(temp)->val.num = x;
  98.     FloatList = temp;
  99.     return FloatList;
  100. }
  101.  
  102. void
  103. KillFloatList(FloatLitVia_t head)
  104. {
  105.     if (head) {
  106.     KillFloatList(Via(head)->next);
  107.     Efree(head);
  108.     }
  109. }
  110.  
  111. int
  112. GetIntValue(ParseTreeVia_t root)
  113. /* Returns the integer value of a constant expression tree. */
  114. {
  115.     int                             result;
  116.     result = 0;
  117.     if (root) {
  118.     switch (Via(root)->kind) {
  119.     case PTF_identifier:
  120.         /*
  121.          * This could probably be more intelligent... I am doing it this
  122.          * way for the preprocessor...
  123.          */
  124.         result = 0;
  125.         break;
  126.     case PTF_intconstant:
  127.         result = Via(root)->data.number;
  128.         break;
  129.     case PTF_typechange:
  130.     case PTF_unary_plus:
  131.         result = GetIntValue(Via(root)->a);
  132.         break;
  133.     case PTF_unary_minus:
  134.         result = 0 - GetIntValue(Via(root)->a);
  135.         break;
  136.     case PTF_enumconstant:
  137.         result = Via(Via(root)->data.thesymbol)->numbers.EnumVal;
  138.         break;
  139.     case PTF_sizeof:
  140.         result = GetTPSize(Via(root)->data.TP);
  141.         break;
  142.     case PTF_logical_and:
  143.         result = GetIntValue(Via(root)->a) && GetIntValue(Via(root)->b);
  144.         break;
  145.     case PTF_logical_neg:
  146.         result = !GetIntValue(Via(root)->a);
  147.         break;
  148.     case PTF_multiply:
  149.         result = GetIntValue(Via(root)->a) * GetIntValue(Via(root)->b);
  150.         break;
  151.     case PTF_divide:
  152.         result = GetIntValue(Via(root)->a) / GetIntValue(Via(root)->b);
  153.         break;
  154.     case PTF_modulo:
  155.         result = GetIntValue(Via(root)->a) % GetIntValue(Via(root)->b);
  156.         break;
  157.     case PTF_add:
  158.         result = GetIntValue(Via(root)->a) + GetIntValue(Via(root)->b);
  159.         break;
  160.     case PTF_subtract:
  161.         result = GetIntValue(Via(root)->a) - GetIntValue(Via(root)->b);
  162.         break;
  163.     case PTF_shift_left:
  164.         result = GetIntValue(Via(root)->a) << GetIntValue(Via(root)->b);
  165.         break;
  166.     case PTF_shift_right:
  167.         result = GetIntValue(Via(root)->a) >> GetIntValue(Via(root)->b);
  168.         break;
  169.     case PTF_lessthan:
  170.         result = GetIntValue(Via(root)->a) < GetIntValue(Via(root)->b);
  171.         break;
  172.     case PTF_greaterthan:
  173.         result = GetIntValue(Via(root)->a) > GetIntValue(Via(root)->b);
  174.         break;
  175.     case PTF_lessthaneq:
  176.         result = GetIntValue(Via(root)->a) <= GetIntValue(Via(root)->b);
  177.         break;
  178.     case PTF_greaterthaneq:
  179.         result = GetIntValue(Via(root)->a) >= GetIntValue(Via(root)->b);
  180.         break;
  181.     case PTF_logical_or:
  182.         result = GetIntValue(Via(root)->a) || GetIntValue(Via(root)->b);
  183.         break;
  184.         /* TODO There are probably more legal possibilities here. */
  185.     case PTF_postincrement:
  186.     case PTF_postdecrement:
  187.     case PTF_preincrement:
  188.     case PTF_predecrement:
  189.     case PTF_assign:
  190.     case PTF_mulassign:
  191.     case PTF_divassign:
  192.     case PTF_modassign:
  193.     case PTF_addassign:
  194.     case PTF_subassign:
  195.     case PTF_leftassign:
  196.     case PTF_rightassign:
  197.     case PTF_andassign:
  198.     case PTF_xorassign:
  199.     case PTF_orassign:
  200.         SyntaxError("Side effects not allowed in constant expressions");
  201.         break;
  202.     default:
  203.         result = 0;
  204.         VeryBadParseError("Unrecognized expression in GetIntValue");
  205.         break;
  206.     }
  207.     }
  208.     return result;
  209. }
  210.  
  211. /* EXPR__ */
  212. int
  213. GetIDENTIFIER(void)
  214. {
  215.     if (NextIs(IDENTIFIER)) {
  216.     return 1;
  217.     } else if (NextIs(TYPEDEF_NAME)) {
  218.     return 2;
  219.     } else {
  220.     return 0;
  221.     }
  222. }
  223.  
  224. /*
  225.  * The functions for the recursive descent parser appear below. This parser
  226.  * is based on the ANSI grammar, appearing in K&R II.  I received a YACC
  227.  * version of this grammar, which appears to be identical, from John Levine,
  228.  * moderator of comp.compilers.  Levine can be reached at
  229.  * compilers-request@iecc@cambridge.ma.us; I have a grammar from James
  230.  * Roskind, which may be better than the ANSI one.  Roskind's grammar handles
  231.  * redef of typedef names and I know that it has been extensively tested and
  232.  * debugged recently. Roskind is jar@ileaf.com.  Roskind's grammar was not
  233.  * used for this compiler.
  234.  */
  235.  
  236. int
  237. CountArgs(ParseTreeVia_t list)
  238. {
  239.     if (Via(list)->kind == PTF_argument_list) {
  240.     return 1 + CountArgs(Via(list)->b);
  241.     } else {
  242.     return 1;
  243.     }
  244. }
  245.  
  246. void
  247. ProtoTypeCheck(SymListVia_t prot,
  248.            ParseTreeVia_t * carg,
  249.            int isellipsis)
  250. {
  251.     SYMVia_t                        param;
  252.     ParseTreeVia_t                  prevcarg;
  253.     int                             done, iscount, sbcount, ndx;
  254.     done = 0;
  255.     iscount = 0;
  256.     sbcount = Via(prot)->count;
  257.     ndx = CountArgs(*carg);
  258.     while (!done) {
  259.     prevcarg = *carg;
  260.     if (Via((*carg))->kind == PTF_argument_list) {
  261.         /* Check Via(carg)->a against item ndx in prot */
  262.         param = NULL;
  263.         if (ndx <= Via(prot)->count)
  264.         param = TableGetNum(prot, ndx);
  265.         if (param) {
  266.         CallCoerce(GetSymTP(param), &(Via((*carg))->a));
  267.         } else {
  268.         assert(isellipsis);
  269.         PtrGenerate(&(Via((*carg))->a));
  270.         StandardIntPromote(&(Via((*carg))->a));
  271.         StandardFloatPromote(&(Via((*carg))->a));
  272.         }
  273.         carg = &((Via(prevcarg))->b);    /* Next arg. */
  274.         ndx--;
  275.     } else {
  276.         /* Last arg. */
  277.         /* Check carg against item ndx in prot */
  278.         param = NULL;
  279.         if (ndx <= Via(prot)->count)
  280.         param = TableGetNum(prot, ndx);
  281.         if (param) {
  282.         CallCoerce(GetSymTP(param), carg);
  283.         } else {
  284.         assert(isellipsis);
  285.         PtrGenerate(carg);
  286.         StandardIntPromote(carg);
  287.         StandardFloatPromote(carg);
  288.         }
  289.         done = 1;
  290.     }
  291.     iscount++;
  292.     }
  293.     if (!isellipsis) {
  294.     if (iscount != sbcount) {
  295.         SemanticError("Wrong number of args to function");
  296.     }
  297.     }
  298. }
  299.  
  300. int
  301. GetMessageKey(void)
  302. {
  303.     return GetIDENTIFIER();    /* TODO needs more */
  304. }
  305.  
  306. ParseTreeVia_t
  307. Do_postfix_expr(void)
  308. {
  309.     /*
  310.      * primary_expr : IDENTIFIER | message send | INTCONSTANT | FLOATCONSTANT
  311.      * | STRING_LITERAL | '(' expr ')' ;
  312.      */
  313.  
  314.     /*
  315.      * postfix_expr : primary_expr | postfix_expr '[' expr ']' | postfix_expr
  316.      * '(' ')' | postfix_expr '(' argument_expr_list ')' | postfix_expr '.'
  317.      * IDENTIFIER | postfix_expr PTR_OP IDENTIFIER | postfix_expr INC_OP |
  318.      * postfix_expr DEC_OP ;
  319.      */
  320.  
  321.     /*
  322.      * I have merged primary expr and postfix expr to form a single routine.
  323.      * Type checking of identifiers will occur here.  The procedure is as
  324.      * follows : for INTCONSTANT (CHARCONSTANT), FLOATCONSTANT,
  325.      * STRING_LITERAL, assign the type based on what is known (STRING_LITERAL
  326.      * is trivial). For IDENTIFIER, look up its type (if it is available, no
  327.      * problem). If its type can not be found, then check the next token.  If
  328.      * it is a '(', then do an implicit declaration.  Be sure to putback the
  329.      * paren, or handle the whole function call. Note that the routine is
  330.      * broken into two halves. Even though I merged the two, I did not
  331.      * integrate them well.
  332.      */
  333.  
  334.     ParseTreeVia_t                  result;
  335.     ParseTreeVia_t                  tmp;
  336.     int                             donepostfixing;
  337.     TypeRecordVia_t                 resulttype;
  338.     SYMVia_t                        ident;
  339.     int                             LeftUndeclared;
  340.     char                            idfound[128];
  341.     int                             ndx;
  342.     int                             done;
  343.     ParseTreeVia_t                 *carg;
  344.     ParseTreeVia_t                  prevcarg;
  345.     int                             iscount;
  346.     LeftUndeclared = 0;
  347.     /*
  348.      * This identifier COULD also be a typedefname, iff that typedef name is
  349.      * in the current local symbol table.
  350.      */
  351.     if (GetIDENTIFIER()) {
  352.     ident = LookUpSymbol(LastToken);
  353.     if (ident) {
  354.         if (Via(ident)->storage_class == SCC_enum) {
  355.         result = BuildTreeNode(PTF_enumconstant, NULL, NULL, NULL);
  356.         SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  357.         SetTreeLValue(result, 0);
  358.         Via(result)->data.thesymbol = ident;
  359.         } else {
  360.         Via(ident)->numbers.CountUses++;
  361.         result = BuildTreeNode(PTF_identifier, NULL, NULL, NULL);
  362.         SetTreeTP(result, GetSymTP(ident));
  363.         if (GetTreeTP(result)) {
  364.             SetTreeLValue(result, StartLValue(GetTreeTP(result)));
  365.         }
  366.         Via(result)->data.thesymbol = ident;
  367.         }
  368.     } else {
  369.         strcpy(idfound, LastToken);
  370.         LeftUndeclared = 1;
  371.         result = BuildTreeNode(PTF_identifier, NULL, NULL, NULL);
  372.         SetTreeTP(result, 0);
  373.         SetTreeLValue(result, 0);
  374.         Via(result)->data.thesymbol = NULL;
  375.     }
  376.     } else if (NextIs(CHARCONSTANT)) {    /* Note that int and char constants
  377.                      * are handled identically. */
  378.     result = BuildTreeNode(PTF_intconstant, NULL, NULL, NULL);
  379.     SetTreeTP(result, 0);
  380.     SetTreeLValue(result, 0);
  381.     Via(result)->data.number = LastIntegerConstant;
  382.     if (strlen(LastToken) > 2) {
  383.         SetTreeTP(result, BuildTypeRecord(0, TRC_long, SGN_unsigned));
  384.     }
  385.     if (!(GetTreeTP(result)) && (strlen(LastToken) > 1)) {
  386.         SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_unsigned));
  387.     }
  388.     if (!GetTreeTP(result)) {
  389.         if (gProject->itsOptions->signedChars) {
  390.         SetTreeTP(result, BuildTypeRecord(0, TRC_char, SGN_signed));
  391.         } else {
  392.         SetTreeTP(result, BuildTypeRecord(0, TRC_char, SGN_unsigned));
  393.         }
  394.     }
  395.     } else if (NextIs(INTCONSTANT)) {
  396.     int                             sufndx;
  397.     int                             YU, YL;
  398.     YU = YL = 0;
  399.     result = BuildTreeNode(PTF_intconstant, NULL, NULL, NULL);
  400.     SetTreeLValue(result, 0);
  401.     Via(result)->data.number = LastIntegerConstant;
  402.     sufndx = 0;
  403.     while (LastToken[sufndx]) {
  404.         switch (LastToken[sufndx]) {
  405.         case 'U':
  406.         YU = 1;
  407.         break;
  408.         case 'L':
  409.         YL = 1;
  410.         break;
  411.         default:
  412.         break;
  413.         }
  414.         sufndx++;
  415.     }
  416.     if (YU) {
  417.         if (YL) {
  418.         SetTreeTP(result, BuildTypeRecord(0, TRC_long, SGN_unsigned));
  419.         } else {
  420.         SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_unsigned));
  421.         }
  422.     } else {
  423.         if (YL) {
  424.         SetTreeTP(result, BuildTypeRecord(0, TRC_long, SGN_signed));
  425.         } else {
  426.         SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  427.         }
  428.     }
  429.     } else if (NextIs(FLOATCONSTANT)) {
  430.     FloatLitVia_t                   lit;
  431.     result = BuildTreeNode(PTF_floatconstant, NULL, NULL, NULL);
  432.     SetTreeTP(result, BuildTypeRecord(0, TRC_longdouble, SGN_unknown));
  433.     SetTreeLValue(result, 0);
  434.     lit = AddFloatLit(LastFloatingConstant);
  435.     Via(result)->data.FLit = lit;
  436.     } else if (NextIs(STRING_LITERAL)) {
  437.         SYMVia_t                        lit;
  438.         result = BuildTreeNode(PTF_string_literal, NULL, NULL, NULL);
  439.         lit = TableSearch(StringLits, (LastToken));
  440.         if (lit) {
  441.             DuplicateStringLits++;
  442.         } else {
  443.             lit = TableAdd(StringLits, (LastToken));
  444.         }
  445.         if (!(Via(lit)->M68kDef.Loc)) {
  446.             Via(lit)->M68kDef.Loc = BuildARegLabelDisplace(5, MakeLitLabel(NextLitLabel++));
  447.         }
  448.         MakeLocGlobal(Via(lit)->M68kDef.Loc);
  449.         Via(result)->data.SLit = lit;
  450.         /* The type of this expression is array of char. */
  451.         /* We immediately do the pointer generation to char * */
  452.         if (gProject->itsOptions->signedChars) {
  453.             SetTreeTP(result, BuildTypeRecord(0, TRC_char, SGN_signed));
  454.         } else {
  455.             SetTreeTP(result, BuildTypeRecord(0, TRC_char, SGN_unsigned));
  456.         }
  457.         SetTreeTP(result, BuildTypeRecord(GetTreeTP(result), TRC_pointer, SGN_unknown));
  458.         SetTreeLValue(result, 0);
  459.     } else if (NextIs(PASCSTRING_LITERAL)) {
  460.         SYMVia_t                        lit;
  461.         result = BuildTreeNode(PTF_string_literal, NULL, NULL, NULL);
  462.         lit = TableSearch(StringLits, (LastToken));
  463.         if (lit) {
  464.             DuplicateStringLits++;
  465.         } else {
  466.             lit = TableAdd(StringLits, (LastToken));
  467.         }
  468.         Via(lit)->SymbolFlags |= ISPASCALSTRING;
  469.         if (!(Via(lit)->M68kDef.Loc))
  470.             Via(lit)->M68kDef.Loc = BuildARegLabelDisplace(5, MakeLitLabel(NextLitLabel++));
  471.         MakeLocGlobal(Via(lit)->M68kDef.Loc);
  472.         Via(result)->data.SLit = lit;
  473.         /* The type of this expression is array of char. */
  474.         /* We immediately do the pointer generation to char * */
  475.         if (gProject->itsOptions->signedChars) {
  476.             SetTreeTP(result, BuildTypeRecord(0, TRC_char, SGN_signed));
  477.         } else {
  478.             SetTreeTP(result, BuildTypeRecord(0, TRC_char, SGN_unsigned));
  479.         }
  480.         SetTreeTP(result, BuildTypeRecord(GetTreeTP(result), TRC_pointer, SGN_unknown));
  481.         SetTreeLValue(result, 0);
  482.     } else if (NextIs('(')) {
  483.     result = Do_expr();
  484.     /*
  485.      * No modification of the type or lvalue status of the resulting
  486.      * expression is necessary.
  487.      */
  488.     if (!NextIs(')')) {
  489.         SyntaxError("Missing right parenthesis");
  490.     }
  491.     } else {
  492.     result = NULL;
  493.     }
  494.  
  495.     /* The above portion is do_primary_expr() */
  496.  
  497.     if (result) {
  498.     donepostfixing = 0;
  499.     while (!donepostfixing) {
  500.         FetchToken();
  501.         switch (LastTokenKind) {
  502.         case '[':
  503.         if (LeftUndeclared) {
  504.             SemanticError2("Undeclared identifier : ", idfound);
  505.             ident = TableAdd(GlobalSymbolTable, (idfound));
  506.             SetSymTP(ident, BuildTypeRecord(0, TRC_int, SGN_signed));
  507.             Via(ident)->numbers.CountUses++;
  508.             LeftUndeclared = 0;
  509.             SetTreeTP(result, GetSymTP(ident));
  510.             SetTreeLValue(result, 0);
  511.             Via(result)->data.thesymbol = ident;
  512.         }
  513.         tmp = Do_expr();
  514.         if (NextIs(']')) {
  515.             if (tmp) {
  516.             PtrGenerate(&result);
  517.             PtrGenerate(&tmp);
  518.             if ((resulttype = (isPointerType(GetTreeTP(result)))) != 0) {
  519.                 if (!isIntegralType(GetTreeTP(tmp))) {
  520.                 TypeError("Array subscript here must be of integral type");
  521.                 }
  522.             } else {
  523.                 if ((resulttype = isPointerType(GetTreeTP(tmp))) != 0) {
  524.                 if (!isIntegralType(GetTreeTP(result))) {
  525.                     TypeError("Array subscript here must be pointer type");
  526.                 }
  527.                 } else {
  528.                 TypeError("Either array base or subscript must be a pointer.");
  529.                 }
  530.             }
  531.             StandardIntPromote(&result);
  532.             StandardIntPromote(&tmp);
  533.             result = BuildTreeNode(PTF_array_subscript, result, tmp, NULL);
  534.             SetTreeTP(result, resulttype);
  535.             if (!isArrayType(resulttype)) {
  536.                 SetTreeLValue(result, 1);
  537.             } else {
  538.                 SetTreeLValue(result, 0);
  539.             }
  540.             /*
  541.              * TYPERULE We have two expressions, result, and tmp.
  542.              * One of these two must have type pointer to X, and
  543.              * the other must have integral type. The resulting
  544.              * postfix expression has type X. Note that according
  545.              * to K&R ][, section A7.1, Pointer Generation, an
  546.              * expression of type "array of X", is converted to
  547.              * type "pointer to X", and the value of the
  548.              * expression is the pointer to the first element in
  549.              * the array. Such a type conversion does not take
  550.              * place if the expression is the operand of the
  551.              * unary & operator, or of ++, --, sizeof, or as the
  552.              * left operand of an assignment operator, or the .
  553.              * operator.
  554.              */
  555.             /*
  556.              * QQQQ WHEN and WHERE should the implementation of
  557.              * Pointer Generation, K&R A7.1, take place ?
  558.              */
  559.             } else {
  560.             SyntaxError("Expecting array subscript expression");
  561.             }
  562.         } else {
  563.             SyntaxError("Missing right bracket");
  564.         }
  565.         break;
  566.         case '(':{
  567.             /*
  568.              * TYPERULE The expr in result must have type pointer to
  569.              * function returning X, and the resulting postfix expr
  570.              * has type X.  Note that according to K&R ][, section
  571.              * A7.1, Pointer Generation, an expression of type
  572.              * "function returning X", except when used as the
  573.              * operand of the "address of" operator, is converted to
  574.              * type "pointer to function returning X."  The result is
  575.              * not an lvalue.
  576.              */
  577.             TypeRecordVia_t                 ftype;
  578.             TypeRecordVia_t                 functype;
  579.             SymListVia_t                    prot;
  580.             if (LeftUndeclared) {
  581.                 UserWarning2(WARN_implicitdecl, idfound);
  582.                 if (gProject->itsOptions->requireProtos) {
  583.                     TypeError("Prototypes required");
  584.                 }
  585.                 ident = TableAdd(CurrentSymbols(), idfound);
  586.                 SetSymTP(ident, BuildTypeRecord(0, TRC_int, SGN_signed));
  587.                 Via(ident)->storage_class = SCC_extern;
  588.                 Via(ident)->numbers.CountUses++;
  589.                 SetSymTP(ident, BuildTypeRecord(GetSymTP(ident), TRC_OLDfunction, SGN_unknown));
  590.                 if (gProject->itsOptions->bigGlobals) {
  591.                     Via(ident)->M68kDef.Loc = BuildLargeGlobal(MakeUserLabel(idfound));
  592.                     MakeLocGlobal(Via(ident)->M68kDef.Loc);
  593.                 } else {
  594.                     Via(ident)->M68kDef.Loc = BuildARegLabelDisplace(5, MakeUserLabel(idfound));
  595.                     MakeLocGlobal(Via(ident)->M68kDef.Loc);
  596.                 }
  597.                 SetLocSZ(Via(ident)->M68kDef.Loc, M68_TypeSize(Via(ident)->TP));
  598.                 LeftUndeclared = 0;
  599.                 SetTPMembers(GetSymTP(ident), RawTable(11));
  600.                 SetTreeTP(result, GetSymTP(ident));
  601.                 SetTreeLValue(result, 0);
  602.                 Via(result)->data.thesymbol = ident;
  603.             }
  604.             /*
  605.              * Here, if result is holding an expression of the form
  606.              * (*fp), then this is a call thru a function pointer,
  607.              * and the user has specified indirection (pre ANSI).  We
  608.              * have to get rid of the indirection.
  609.              */
  610.             if (Via(result)->kind == PTF_deref) {
  611.             ParseTreeVia_t                  tmp;
  612.             tmp = result;
  613.             result = Via(result)->a;
  614.             Via(tmp)->a = NULL;
  615.             FreeTree(tmp);
  616.             }
  617.             ftype = functype = GetFuncType(GetTreeTP(result));
  618.             if (!functype) {
  619.             ftype = functype = GetFuncType(isPointerType(GetTreeTP(result)));
  620.             }
  621.             assert(functype);
  622.             prot = GetTPMembers(ftype);
  623.             if (!(resulttype = isFunctionType(isPointerType(GetTreeTP(result))))) {
  624.             if (Via(result)->kind != PTF_deref) {
  625.                 PtrGenerate(&result);
  626.             }
  627.             }
  628.             if (!(resulttype = isFunctionType(isPointerType(GetTreeTP(result))))) {
  629.             SemanticError("Call of non-function");
  630.             }
  631.             if (NextIs(')')) {
  632.             if (GetTPKind(ftype) == TRC_ANSIfunction) {
  633.                 SemanticError("This function requires arguments");
  634.             }
  635.             /*
  636.              * The above error assumes that ANSIfunctions are the
  637.              * only ones which have arguments.  An ANSI function
  638.              * with no arguments is internally represented as a
  639.              * NOARGS function. We do not care if there is a call
  640.              * to an old style function which is declared with
  641.              * args, with no args.
  642.              */
  643.             result = BuildTreeNode(PTF_function_call, result, NULL, NULL);
  644.             Via(result)->data.TP = functype;
  645.             SetTreeTP(result, resulttype);
  646.             SetTreeLValue(result, 0);
  647.             } else {
  648.             tmp = Do_argument_expr_list();
  649.             /*
  650.              * The arg expr list is a list of expressions. If
  651.              * there were none, tmp is NULL.  If there was more
  652.              * than one, then Via(tmp)->kind ==
  653.              * PTF_argument_list.  Otherwise, tmp is simply the
  654.              * single expr which was an arg.  If there was more
  655.              * than one, then the list is in reverse order.  The
  656.              * first arg is in Via(tmp)->a and the leftover args
  657.              * are in yet another list (same properties apply) in
  658.              * Via(tmp)->b.  So, if there were 2 args, then
  659.              * Via(tmp)->a is the second arg, and Via(tmp)->b is
  660.              * the second.
  661.              */
  662.             if (!NextIs(')')) {
  663.                 SyntaxError("Missing right parenthesis");
  664.             }
  665.             if (tmp) {
  666.                 if (GetTPKind(ftype) == TRC_NOARGSfunction) {
  667.                 SemanticError("This function has no parameters");
  668.                 } else if ((GetTPKind(ftype) == TRC_ANSIELLIPSISfunction) ||
  669.                    (GetTPKind(ftype) == TRC_ANSIfunction)) {
  670.                 /*
  671.                  * Here we are type checking the arguments in
  672.                  * tmp (the argument expr list for the
  673.                  * function call) against the proto in prot.
  674.                  * tmp is a parse tree and prot is a symbol
  675.                  * table.
  676.                  */
  677.                 ProtoTypeCheck(prot, &tmp, (GetTPKind(ftype) == TRC_ANSIELLIPSISfunction));
  678.                 result = BuildTreeNode(PTF_function_call, result, tmp, NULL);
  679.                 Via(result)->data.TP = functype;
  680.                 SetTreeTP(result, resulttype);
  681.                 SetTreeLValue(result, 0);
  682.                 } else {
  683.                 done = 0;
  684.                 iscount = 0;
  685.                 ndx = 1;
  686.                 carg = &tmp;
  687.                 while (!done) {
  688.                     prevcarg = *carg;
  689.                     if (Via((*carg))->kind == PTF_argument_list) {
  690.                     PtrGenerate(&(Via((*carg))->a));
  691.                     StandardIntPromote(&(Via((*carg))->a));
  692.                     StandardFloatPromote(&(Via((*carg))->a));
  693.                     } else {
  694.                     /* Last arg. */
  695.                     PtrGenerate(carg);
  696.                     StandardIntPromote(carg);
  697.                     StandardFloatPromote(carg);
  698.                     done = 1;
  699.                     }
  700.                     carg = &((Via(prevcarg))->b);    /* Next arg. */
  701.                     ndx++;
  702.                     iscount++;
  703.                 }
  704.                 result = BuildTreeNode(PTF_function_call, result, tmp, NULL);
  705.                 Via(result)->data.TP = functype;
  706.                 SetTreeTP(result, resulttype);
  707.                 SetTreeLValue(result, 0);
  708.                 }
  709.             } else {
  710.                 SyntaxError("Expecting argument list for func call");
  711.             }
  712.             }
  713.         }
  714.         break;
  715.         case '.':
  716.         /*
  717.          * TYPERULE The type of result must be a struct or union.
  718.          */
  719.         if (LeftUndeclared) {
  720.             SemanticError2("Undeclared identifier : ", idfound);
  721.             ident = TableAdd(GlobalSymbolTable, (idfound));
  722.             SetSymTP(ident, BuildTypeRecord(0, TRC_int, SGN_signed));
  723.             Via(ident)->numbers.CountUses++;
  724.             LeftUndeclared = 0;
  725.             SetTreeTP(result, GetSymTP(ident));
  726.             SetTreeLValue(result, 0);
  727.             Via(result)->data.thesymbol = ident;
  728.         }
  729.         if (!isStructUnionType(GetTreeTP(result))) {
  730.             TypeError("Struct or union type required here for .");
  731.         }
  732.         if (NextIs(IDENTIFIER)) {
  733.             /*
  734.              * TYPERULE The identifier must be the name of a member
  735.              * of the struct/union in result. The type of the
  736.              * resulting postfix expr is the type of the named
  737.              * member.  It is an lvalue if the member is not an array
  738.              * type.
  739.              */
  740.             SYMVia_t                        memb;
  741.             if ((memb = isMemberOf(GetTreeTP(result), LastToken)) != 0) {
  742.             ParseTreeVia_t                  old;
  743.             old = result;
  744.             result = BuildTreeNode(PTF_struct_member, result, NULL, NULL);
  745.             Via(result)->data.thesymbol = memb;
  746.             SetTreeTP(result, GetSymTP(memb));
  747.             if (!isArrayType(GetSymTP(memb))) {
  748.                 if (Via(old)->kind == PTF_identifier) {
  749.                 if (GetTPQual(Via(Via(old)->data.thesymbol)->TP) == SCC_const) {
  750.                     SetTreeLValue(result, 0);
  751.                 } else {
  752.                     SetTreeLValue(result, 1);
  753.                 }
  754.                 } else {
  755.                 SetTreeLValue(result, 1);
  756.                 }
  757.             } else {
  758.                 SetTreeLValue(result, 0);
  759.             }
  760.             } else {
  761.             SemanticError("This is not a member of the given struct/union (.)");
  762.             }
  763.         } else {
  764.             SyntaxError("Expecting identifier for field name");
  765.         }
  766.         break;
  767.         case PTR_OP:
  768.         /*
  769.          * TYPERULE The type of result must be ptr to struct or
  770.          * union.
  771.          */
  772.         if (LeftUndeclared) {
  773.             SemanticError2("Undeclared identifier : ", idfound);
  774.             ident = TableAdd(GlobalSymbolTable, (idfound));
  775.             SetSymTP(ident, BuildTypeRecord(0, TRC_int, SGN_signed));
  776.             Via(ident)->numbers.CountUses++;
  777.             LeftUndeclared = 0;
  778.             SetTreeTP(result, GetSymTP(ident));
  779.             SetTreeLValue(result, 0);
  780.             Via(result)->data.thesymbol = ident;
  781.         }
  782.         if (!isStructUnionType(isPointerType(GetTreeTP(result)))) {
  783.             TypeError("Struct or union type required for ->");
  784.         }
  785.         if (NextIs(IDENTIFIER)) {
  786.             /*
  787.              * TYPERULE The identifier must be the name of a member
  788.              * of the struct/union in result. The type of the
  789.              * resulting postfix expr is the type of the named
  790.              * member.  It is an lvalue if the member is not an array
  791.              * type.
  792.              */
  793.             SYMVia_t                        memb;
  794.             if ((memb = isMemberOf(isPointerType(GetTreeTP(result)), LastToken)) != 0) {
  795.             ParseTreeVia_t                  old;
  796.             old = result;
  797.             result = BuildTreeNode(PTF_struct_indirect_member, result, NULL, NULL);
  798.             Via(result)->data.thesymbol = memb;
  799.             SetTreeTP(result, GetSymTP(memb));
  800.             if (!isArrayType(GetSymTP(memb))) {
  801.                 SetTreeLValue(result, 1);
  802.             } else {
  803.                 SetTreeLValue(result, 0);
  804.             }
  805.             } else {
  806.             SemanticError("This is not a member of the given struct/union (->)");
  807.             }
  808.         } else {
  809.             SyntaxError("Expecting identifier for field name");
  810.         }
  811.         break;
  812.         case INC_OP:{
  813.             /*
  814.              * TYPERULE The operand must have arithmetic type, and it
  815.              * must be an lvalue.  The resulting type is the same,
  816.              * but it is not an lvalue.
  817.              */
  818.             ParseTreeVia_t                  tmptree;
  819.             if (LeftUndeclared) {
  820.             SemanticError2("Undeclared identifier : ", idfound);
  821.             ident = TableAdd(GlobalSymbolTable, (idfound));
  822.             SetSymTP(ident, BuildTypeRecord(0, TRC_int, SGN_signed));
  823.             Via(ident)->numbers.CountUses++;
  824.             LeftUndeclared = 0;
  825.             SetTreeTP(result, GetSymTP(ident));
  826.             SetTreeLValue(result, 0);
  827.             Via(result)->data.thesymbol = ident;
  828.             }
  829.             if (!isBooleanType(GetTreeTP(result))) {
  830.             TypeError("++ requires arithmetic or pointer type");
  831.             }
  832.             if (!GetTreeLValue(result)) {
  833.             SemanticError("Operand of ++ must be an lvalue");
  834.             }
  835.             tmptree = result;
  836.             result = BuildTreeNode(PTF_postincrement, tmptree, NULL, NULL);
  837.             SetTreeLValue(result, 0);
  838.             SetTreeTP(result, GetTreeTP(tmptree));
  839.         }
  840.         break;
  841.         case DEC_OP:{
  842.             /*
  843.              * TYPERULE The operand must have arithmetic type, and it
  844.              * must be an lvalue.  The resulting type is the same,
  845.              * but it is not an lvalue.
  846.              */
  847.             ParseTreeVia_t                  tmptree;
  848.             if (LeftUndeclared) {
  849.             SemanticError2("Undeclared identifier : ", idfound);
  850.             ident = TableAdd(GlobalSymbolTable, (idfound));
  851.             SetSymTP(ident, BuildTypeRecord(0, TRC_int, SGN_signed));
  852.             Via(ident)->numbers.CountUses++;
  853.             LeftUndeclared = 0;
  854.             SetTreeTP(result, GetSymTP(ident));
  855.             SetTreeLValue(result, 0);
  856.             Via(result)->data.thesymbol = ident;
  857.             }
  858.             if (!isBooleanType(GetTreeTP(result))) {
  859.             TypeError("-- requires arithmetic or pointer type");
  860.             }
  861.             if (!GetTreeLValue(result)) {
  862.             SemanticError("Operand of -- must be an lvalue");
  863.             }
  864.             tmptree = result;
  865.             result = BuildTreeNode(PTF_postdecrement, tmptree, NULL, NULL);
  866.             SetTreeLValue(result, 0);
  867.             SetTreeTP(result, GetTreeTP(tmptree));
  868.         }
  869.         break;
  870.         default:
  871.         donepostfixing = 1;
  872.         UnFetchToken();
  873.         }
  874.     }
  875.     }
  876.     if (result) {
  877.     if (!GetTreeTP(result)) {
  878.         if (InPreprocIf) {
  879.         SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  880.         SetTreeLValue(result, 0);
  881.         Via(result)->data.thesymbol = NULL;
  882.         } else {
  883.         SemanticError2("Undeclared identifier : ", idfound);
  884.         ident = TableAdd(GlobalSymbolTable, (idfound));
  885.         SetSymTP(ident, BuildTypeRecord(0, TRC_int, SGN_signed));
  886.         Via(ident)->numbers.CountUses++;
  887.         LeftUndeclared = 0;
  888.         SetTreeTP(result, GetSymTP(ident));
  889.         SetTreeLValue(result, 0);
  890.         Via(result)->data.thesymbol = ident;
  891.         }
  892.     }
  893.     }
  894.     return result;
  895. }
  896.  
  897. ParseTreeVia_t
  898. Do_argument_expr_list(void)
  899. {
  900.     /*
  901.      * argument_expr_list : assignment_expr | argument_expr_list ','
  902.      * assignment_expr ;
  903.      */
  904.  
  905.     ParseTreeVia_t                  result;
  906.     int                             donelisting;
  907.     ParseTreeVia_t                  tmp;
  908.     int                             count;
  909.     count = 0;
  910.     result = Do_assignment_expr();
  911.     if (result) {
  912.     donelisting = 0;
  913.     while (!donelisting) {
  914.         if (NextIs(',')) {
  915.         tmp = Do_assignment_expr();
  916.         if (tmp) {
  917.             result = BuildTreeNode(PTF_argument_list, tmp, result, NULL);
  918.         } else {
  919.             SyntaxError("Expecting argument expr in function call");
  920.         }
  921.         } else {
  922.         donelisting = 1;
  923.         }
  924.     }
  925.     }
  926.     /*
  927.      * QQQQ This routine does not have type rules.  It is simply returning a
  928.      * list of expressions.  As such, the data structures here may not be the
  929.      * best choice, and this routine should probably move farther down in the
  930.      * list.
  931.      */
  932.     return result;
  933. }
  934.  
  935. ParseTreeVia_t
  936. Do_unary_expr(void)
  937. {
  938.     /*
  939.      * unary_expr : postfix_expr | INC_OP unary_expr | DEC_OP unary_expr |
  940.      * unary_operator cast_expr | SIZEOF unary_expr | SIZEOF '(' type_name
  941.      * ')' ;
  942.      */
  943.  
  944.     TypeRecordVia_t                 typerec;
  945.     ParseTreeVia_t                  result = NULL;
  946.     ParseTreeVia_t                  tmp;
  947.     /*
  948.      * TYPERULE For ++ and --, the operand must be an lvalue of arithmetic
  949.      * type, and the result is NOT an lvalue.
  950.      */
  951.     if (NextIs(INC_OP)) {
  952.     tmp = Do_unary_expr();
  953.     if (tmp) {
  954.         if (!isBooleanType(GetTreeTP(tmp))) {
  955.         TypeError("++ requires arithmetic or pointer type");
  956.         }
  957.         if (!GetTreeLValue(tmp)) {
  958.         SemanticError("Operand of ++ must be an lvalue");
  959.         }
  960.         result = BuildTreeNode(PTF_preincrement, tmp, NULL, NULL);
  961.         SetTreeTP(result, GetTreeTP(tmp));
  962.         SetTreeLValue(result, 0);
  963.     } else {
  964.         SyntaxError("Expected unary expr after ++");
  965.     }
  966.     } else if (NextIs(DEC_OP)) {
  967.     tmp = Do_unary_expr();
  968.     if (tmp) {
  969.         if (!isBooleanType(GetTreeTP(tmp))) {
  970.         TypeError("-- requires arithmetic or pointer type");
  971.         }
  972.         if (!GetTreeLValue(tmp)) {
  973.         SemanticError("Operand of -- must be an lvalue");
  974.         }
  975.         result = BuildTreeNode(PTF_predecrement, tmp, NULL, NULL);
  976.         SetTreeTP(result, GetTreeTP(tmp));
  977.         SetTreeLValue(result, 0);
  978.     } else {
  979.         SyntaxError("Expected unary expr after --");
  980.     }
  981.     } else if (NextIs(DEFINED)) {
  982.     int                             needrightparen;
  983.     char                            PStr[128];
  984.     char                            c;
  985.     int                             ndx;
  986.     /*
  987.      * defined is a token which is not always a token.  The isKeyword
  988.      * routine checks the global flag (preprocif) and only returns true
  989.      * iff this flag is true, when it find the token 'defined'. The
  990.      * preproc directives set this flag true when parsing a #if or #elif
  991.      * expression.  The flag is set false immediately after, because the
  992.      * defined() macro is not valid except during preprocessing.
  993.      */
  994.     needrightparen = 0;
  995.     if (NextIs('(')) {
  996.         needrightparen = 1;
  997.     }
  998.     c = NonSpaceCharacter();
  999.     ndx = 0;
  1000.     if (isFirstIDChar(c)) {
  1001.         PStr[ndx++] = c;
  1002.         while (isAnyIDChar(c = TokenCharacter())) {
  1003.         PStr[ndx++] = c;
  1004.         }
  1005.         PStr[ndx] = 0;
  1006.         /*
  1007.          * Now PStr contains the name of the identifer being tested.
  1008.          */
  1009.         PutBackChar(c);
  1010.     } else {
  1011.         PutBackChar(c);
  1012.     }
  1013.     if (ndx) {
  1014.         result = BuildTreeNode(PTF_intconstant, NULL, NULL, NULL);
  1015.         SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  1016.         SetTreeLValue(result, 0);
  1017.         if (isDefined(PStr)) {
  1018.         Via(result)->data.number = 1;
  1019.         } else {
  1020.         Via(result)->data.number = 0;
  1021.         }
  1022.     } else {
  1023.         SyntaxError("Expected identifier after preproc 'defined'");
  1024.     }
  1025.     if (needrightparen) {
  1026.         if (!NextIs(')')) {
  1027.         SyntaxError("Missing right parenthesis");
  1028.         }
  1029.     }
  1030.     } else if (NextIs(SIZEOF)) {
  1031.     if (NextIs('(')) {
  1032.         typerec = Do_type_name();
  1033.         if (typerec) {
  1034.         if (isIncompleteType(typerec)) {
  1035.             TypeError("Incomplete type for sizeof");
  1036.         }
  1037.         if (isBitFieldType(typerec)) {
  1038.             TypeError("Cannot take sizeof a bit field");
  1039.         }
  1040.         result = BuildTreeNode(PTF_sizeof, NULL, NULL, NULL);
  1041.         Via(result)->data.TP = typerec;
  1042.         SetTreeTP(result, BuildTypeRecord(0, TRC_long, SGN_unsigned));
  1043.         SetTreeLValue(result, 0);
  1044.         } else {
  1045.         /*
  1046.          * Here, we will allow sizeof(expr) even though I'm not sure
  1047.          * if it is ANSI.
  1048.          */
  1049.         tmp = Do_conditional_expr();
  1050.         if (tmp) {
  1051.             if (isBitFieldType(GetTreeTP(tmp))) {
  1052.             TypeError("Cannot take sizeof a bit field");
  1053.             }
  1054.             if (isIncompleteType(GetTreeTP(tmp))) {
  1055.             TypeError("Incomplete type for sizeof");
  1056.             }
  1057.             result = BuildTreeNode(PTF_sizeof, NULL, NULL, NULL);
  1058.             Via(result)->data.TP = GetTreeTP(tmp);
  1059.             SetTreeTP(result, BuildTypeRecord(0, TRC_long, SGN_unsigned));
  1060.             SetTreeLValue(result, 0);
  1061.         } else {
  1062.             SyntaxError("Expected unary expr or typename in sizeof");
  1063.         }
  1064.         }
  1065.         if (!NextIs(')')) {
  1066.         SyntaxError("Missing right parenthesis");
  1067.         }
  1068.     } else {
  1069.         tmp = Do_unary_expr();
  1070.         if (tmp) {
  1071.         if (isBitFieldType(GetTreeTP(tmp))) {
  1072.             TypeError("Cannot take sizeof a bit field");
  1073.         }
  1074.         if (isIncompleteType(GetTreeTP(tmp))) {
  1075.             TypeError("Incomplete type for sizeof");
  1076.         }
  1077.         result = BuildTreeNode(PTF_sizeof, NULL, NULL, NULL);
  1078.         Via(result)->data.TP = GetTreeTP(tmp);
  1079.         SetTreeTP(result, BuildTypeRecord(0, TRC_long, SGN_unsigned));
  1080.         SetTreeLValue(result, 0);
  1081.         } else {
  1082.         SyntaxError("Expected unary expr after sizeof");
  1083.         }
  1084.     }
  1085.     } else {
  1086.     Codigo_t                        unaryop;
  1087.     unaryop = Do_unary_operator();
  1088.     if (unaryop) {
  1089.         tmp = Do_cast_expr();
  1090.         if (tmp) {
  1091.         TypeRecordVia_t                 tmptype;
  1092.         switch (unaryop) {
  1093.         case '&':
  1094.             if (Via(tmp)->kind == PTF_identifier) {
  1095.             if (Via(Via(tmp)->data.thesymbol)->storage_class == SCC_register) {
  1096.                 SemanticError("& (address-of) is illegal for register variables");
  1097.             }
  1098.             }
  1099.             if (isBitFieldType(GetTreeTP(tmp))) {
  1100.             SemanticError("& (address-of) is illegal for bit fields");
  1101.             }
  1102.             result = BuildTreeNode(PTF_address_of, tmp, NULL, NULL);
  1103.             SetTreeLValue(result, 0);
  1104.             SetTreeTP(result, BuildTypeRecord(GetTreeTP(tmp), TRC_pointer, SGN_unknown));
  1105.             break;
  1106.         case '*':
  1107.             /* TYPERULE This must be a pointer. */
  1108.             PtrGenerate(&tmp);
  1109.             if (!(tmptype = isPointerType(GetTreeTP(tmp)))) {
  1110.             TypeError("Dereferencing requires expr of pointer type");
  1111.             }
  1112.             result = BuildTreeNode(PTF_deref, tmp, NULL, NULL);
  1113.             SetTreeTP(result, tmptype);
  1114.             if (isArrayType(GetTreeTP(tmp))) {
  1115.             SetTreeLValue(result, 0);
  1116.             } else {
  1117.             SetTreeLValue(result, 1);
  1118.             }
  1119.             break;
  1120.         case '+':
  1121.             /* TYPERULE ??? */
  1122.             if (!isArithmeticType(GetTreeTP(tmp))) {
  1123.             TypeError("Unary plus requires arithmetic type");
  1124.             }
  1125.             result = BuildTreeNode(PTF_unary_plus, tmp, NULL, NULL);
  1126.             SetTreeTP(result, GetTreeTP(tmp));
  1127.             SetTreeLValue(result, 0);
  1128.             break;
  1129.         case '-':
  1130.             /* TYPERULE ??? */
  1131.             if (!isArithmeticType(GetTreeTP(tmp))) {
  1132.             TypeError("Unary minus requires arithmetic type");
  1133.             }
  1134.             result = BuildTreeNode(PTF_unary_minus, tmp, NULL, NULL);
  1135.             SetTreeTP(result, GetTreeTP(tmp));
  1136.             SetTreeLValue(result, 0);
  1137.             break;
  1138.         case '~':
  1139.             /* TYPERULE ??? */
  1140.             if (!isIntegralType(GetTreeTP(tmp))) {
  1141.             TypeError("~ requires integral type");
  1142.             }
  1143.             result = BuildTreeNode(PTF_bitwise_neg, tmp, NULL, NULL);
  1144.             SetTreeTP(result, GetTreeTP(tmp));
  1145.             SetTreeLValue(result, 0);
  1146.             break;
  1147.         case '!':
  1148.             /* TYPERULE ??? */
  1149.             if (!isBooleanType(GetTreeTP(tmp))) {
  1150.             TypeError("! requires arithmetic or pointer type");
  1151.             }
  1152.             result = BuildTreeNode(PTF_logical_neg, tmp, NULL, NULL);
  1153.             SetTreeTP(result, BuildTypeRecord(0, TRC_int, SGN_signed));
  1154.             SetTreeLValue(result, 0);
  1155.             break;
  1156.         default:
  1157.             VeryBadParseError("Illegal token code for unary operator");
  1158.             break;
  1159.         }
  1160.         } else {
  1161.         SyntaxError("Expected expr after unary operator");
  1162.         }
  1163.     } else {
  1164.         result = Do_postfix_expr();
  1165.     }
  1166.     }
  1167.     return result;
  1168. }
  1169.  
  1170. Codigo_t
  1171. Do_unary_operator(void)
  1172. {
  1173.     /*
  1174.      * unary_operator : '&' | '*' | '+' | '-' | '~' | '!' ;
  1175.      */
  1176.  
  1177.     if (NextIs('&')) {
  1178.     return '&';
  1179.     } else if (NextIs('*')) {
  1180.     return '*';
  1181.     } else if (NextIs('+')) {
  1182.     return '+';
  1183.     } else if (NextIs('-')) {
  1184.     return '-';
  1185.     } else if (NextIs('~')) {
  1186.     return '~';
  1187.     } else if (NextIs('!')) {
  1188.     return '!';
  1189.     } else {
  1190.     return 0;
  1191.     }
  1192. }
  1193.